package org.jslaughter.component.ai;

import org.jslaughter.event.eventtype.DamageEvent.DAMAGE_TYPE;
import org.nvframe.component.AbstractComponent;
import org.nvframe.component.ai.Behaviour;
import org.nvframe.component.property.PropertyManager;
import org.nvframe.entity.Entity;
import org.nvframe.manager.ConfigManager;
import org.nvframe.util.settings.SettingsObj;

public class BehaviourImpl extends AbstractComponent implements Behaviour {

	private BEHAVIOUR_TYPE behaviour;
	private String team;
	
	// flags
	public boolean blocksExplosionsFlag;
	public boolean blocksBulletsFlag;
	public boolean blocksMeleeFlag;

	public BehaviourImpl(String id, Entity owner, SettingsObj settings) {
		super(id, owner);

		setBlocksBullets(settings.getBoolean("blocksBullets", false));
		setBlocksExplosions(settings.getBoolean("blocksExplosions", false));
		setBlocksMelee(settings.getBoolean("blocksMelee", false));
		
		behaviour = BEHAVIOUR_TYPE.valueOf(settings.getString("behaviour", BEHAVIOUR_TYPE.NEUTRAL.toString()));
		team = settings.getString("team", "NONE");
	}

	public BEHAVIOUR_TYPE getBehaviour() {
		return behaviour;
	}

	public void setBehaviour(BEHAVIOUR_TYPE behaviour) {
		this.behaviour = behaviour;
	}
	
	public String getTeam() {
		return team;
	}
	
	public boolean damageGetsBlockedBy(Entity target, DAMAGE_TYPE damageType) {
		BehaviourImpl targetBehaviour = (BehaviourImpl) target.getComponent(BehaviourImpl.class);
		
		if(targetBehaviour == null)
			return false;
		
		if(damageType == DAMAGE_TYPE.EXPLOSION && targetBehaviour.isBlocksExplosions())
			return true;
		
		if(damageType == DAMAGE_TYPE.WEAPON_BULLET && targetBehaviour.isBlocksBullets())
			return true;
		
		if(damageType == DAMAGE_TYPE.MELEE && targetBehaviour.isBlocksMelee())
			return true;
		
		return false;
	}
	
	public boolean canDoDamageTo(Entity target, DAMAGE_TYPE damageType) {
		// no damage when attack is blocked
		if(damageGetsBlockedBy(target, damageType))
			return false;
		
		// can't do damage when target has no propertymanager with health
		PropertyManager targetPropMgr = (PropertyManager) target.getComponent(PropertyManager.class);
		
		if(targetPropMgr == null || !targetPropMgr.containsProperty("health"))
			return false;
		
		return true;
	}
	
	public BEHAVIOUR_TYPE getBehaviourTowards(Entity target) {
		BehaviourImpl targetBehaviour = (BehaviourImpl) target.getComponent(BehaviourImpl.class);
		
		// no behaviour => no aggression
		if(targetBehaviour == null)
			return BEHAVIOUR_TYPE.NEUTRAL;
		
		// can't damage root! (mostly for bullets)
		if(owner.getRoot() == target)
			return BEHAVIOUR_TYPE.FRIENDLY;
		
		// same team
		if(!targetBehaviour.getTeam().equals("NONE") && getTeam().equals(targetBehaviour.getTeam()))
			if(ConfigManager.getInstance().getActive("behaviour_friendlyfire"))
				return BEHAVIOUR_TYPE.NEUTRAL;
			else
				return BEHAVIOUR_TYPE.FRIENDLY;
		
		if(targetBehaviour.getTeam().equals("NONE") && 
				!(targetBehaviour.getBehaviour() == BEHAVIOUR_TYPE.HOSTILE))
			return BEHAVIOUR_TYPE.NEUTRAL;
		
		return BEHAVIOUR_TYPE.HOSTILE;
	}
	
	public boolean isBlocksBullets(){ return blocksBulletsFlag; }
	public void setBlocksBullets(boolean flag){	blocksBulletsFlag = flag; }
	
	public boolean isBlocksExplosions(){ return blocksExplosionsFlag; }
	public void setBlocksExplosions(boolean flag){ blocksExplosionsFlag = flag; }
	
	public boolean isBlocksMelee(){ return blocksMeleeFlag; }
	public void setBlocksMelee(boolean flag){ blocksMeleeFlag = flag; }

	public void setTeam(String team) {
		this.team = team;		
	}
}
